﻿using InTheHand.Net.Sockets;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Web.Script.Serialization;
using System.Windows.Forms;

namespace KeepPwdPcInput
{
    public partial class Form1 : Form
    {
        readonly Guid OurServiceClassId = new Guid("{29913A2D-EB93-40cf-BBB8-DEEE26452197}");
        readonly string OurServiceName = "keepPwdPcInputer";
        BluetoothListener _lsnr;
        public delegate void msgdele2(int flag, char msg);
        public delegate void msgdele(MsgObj msg);
        static string websitePost = "9098";
        static string websitePath = "WebSite/";
        static HttpListener sSocket;
        static string chromeCurl;
        KeepPwdPcInput.ConfigHelper.config config;
        bool socketWorking = false, bluetoothWorking = false;
        Socket m_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public Form1()
        {
            config = ConfigHelper.getCfg();

            InitializeComponent();
            StartListener();
            if (config != null)
            {
                new Thread(delegate()
                {
                    Thread.Sleep(500);
                    Mhide(null);
                }).Start();
            }

            sSocket = new HttpListener();
            sSocket.IgnoreWriteExceptions = true;

            sSocket.Prefixes.Add("http://localhost:" + websitePost + "/" + websitePath);
            sSocket.Start();
            Console.WriteLine("WebServer Start Successed.......");
            sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);
            Console.WriteLine("open http.......");

        }

        static void GetContextCallBack(IAsyncResult ar)
        {
            try
            {
                sSocket = ar.AsyncState as HttpListener;
                HttpListenerContext ctx = sSocket.EndGetContext(ar);
                sSocket.BeginGetContext(new AsyncCallback(GetContextCallBack), sSocket);

                var url = ctx.Request.Url.ToString();
                int a = url.IndexOf(websitePost + "/" + websitePath);
                if (a > 0)
                {
                    url = url.Substring(a + (websitePost + "/" + websitePath).Length);
                }
                else
                {
                    a = url.IndexOf(websitePost);
                    url = url.Substring(0, a) + websitePost + "/" + websitePath;
                    ctx.Response.Redirect(url);
                    ctx.Response.Close();
                    return;
                }
                chromeCurl = url.Substring(5);
                Console.WriteLine(url.Substring(5));
                ctx.Response.Close();
            }
            catch
            {
            }
        }

        public void reSet()
        {
            config = ConfigHelper.getCfg();
            StartListener();
        }

        private void Mhide(MsgObj msg)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new msgdele(Mhide), msg);
            }
            else
            {
                this.Hide();
            }
        }

        private string base64e(string str)
        {
            byte[] resultArray = UTF8Encoding.UTF8.GetBytes(str);
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }

        private string base64d(string str)
        {
            byte[] resultArray = Convert.FromBase64String(str);
            return UTF8Encoding.UTF8.GetString(resultArray);
        }

        private void StartListener()
        {
            if (config == null)
            {
                label3.Text = "未启动";
                label4.Text = "未启动";
                return;
            }

            if (config.connType == "1" || config.connType == "3")
            {
                if (!bluetoothWorking)
                {
                    try
                    {
                        bluetoothWorking = true;
                        var lsnr = new BluetoothListener(OurServiceClassId);
                        lsnr.ServiceName = OurServiceName;
                        lsnr.Start();
                        _lsnr = lsnr;
                        ThreadPool.QueueUserWorkItem(ListenerAccept_Runner, lsnr);

                        label3.Text = "已启动";
                    }
                    catch
                    {
                        bluetoothWorking = false;
                        label3.Text = "启动失败";
                    }
                }
                else
                {
                    label3.Text = "已启动";
                }
            }
            else
            {
                if (bluetoothWorking)
                {
                    bluetoothWorking = false;
                    _lsnr.Stop();
                }
                label3.Text = "未启动";
            }

            if (config.connType == "2" || config.connType == "3")
            {
                if (!socketWorking)
                {
                    try
                    {
                        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, config.port);
                        m_serverSocket.Bind(localEndPoint);
                        socketWorking = true;
                        ThreadPool.QueueUserWorkItem(socketListenerAccept_Runner, m_serverSocket);
                        label4.Text = "已启动";

                    }
                    catch
                    {
                        socketWorking = false;
                        label4.Text = "启动失败";
                    }
                }
                else
                {
                    label4.Text = "已启动";
                }
            }
            else 
            {
                if (socketWorking)
                {
                    socketWorking = false;
                    try
                    {
                        m_serverSocket.Close();
                    }
                    catch { }
                    //mRecognition.stop();
                }
                label4.Text = "未启动";
            }
        }

        void ListenerAccept_Runner(object state)
        {
            var lsnr = (BluetoothListener)_lsnr;
            while (bluetoothWorking)
            {
                try
                {
                    var conn = lsnr.AcceptBluetoothClient();
                    var peer = conn.GetStream();
                    ThreadPool.QueueUserWorkItem(ReadMessagesToEnd, peer);
                }
                catch { }
            }
        }

        void socketListenerAccept_Runner(object obj)
        {
            m_serverSocket.Listen(500);
            while (socketWorking)
            {
                try
                {
                    Socket newSocket = m_serverSocket.Accept();
                    NetworkStream ns = new NetworkStream(newSocket);
                    ThreadPool.QueueUserWorkItem(ReadMessagesToEnd2, ns);
                }
                catch { }
            }
            
        }

        private void ReadMessagesToEnd(object peer)
        {
            var rdr = new StreamReader((Stream)peer);
            var rdw = new StreamWriter((Stream)peer);
            String line2 = "";
            while (bluetoothWorking)
            {
                string line = null;
                try
                {
                    line = rdr.ReadLine();
                }
                catch { }
                if (line == null)
                {
                    break;
                }
                else if (line == "" && line2 != "")
                {
                    try
                    {
                        string msg = AES.Decrypt(line2, config.connKey);
                        MsgObj m = DeserializeJson<MsgObj>(msg);
                        if (m.type != "3" && m.type != "4")
                        {
                            sendmsg(m);
                            rdw.Write("\0");
                            rdw.Flush();
                        }
                        else if (m.type == "4")
                        {
                            rdw.Write("1\0");
                            rdw.Flush();
                        }
                        else
                        {
                            rdw.Write((chromeCurl == null ? "0" : chromeCurl) + "\0");
                            rdw.Flush();
                        }
                        line2 = "";
                    }
                    catch { }
                    break;
                }
                else
                {
                    line2 += line;
                }
            }
            try
            {
                Thread.Sleep(1000);
                rdr.Close();
                rdw.Close();
            }
            catch { }
        }
        private void ReadMessagesToEnd2(object peer)
        {
            var rdr = new StreamReader((Stream)peer);
            var rdw = new StreamWriter((Stream)peer);
            String line2 = "";
            while (socketWorking)
            {
                string line = null;
                try
                {
                    line = rdr.ReadLine();
                }
                catch { }
                if (line == null)
                {
                    break;
                }
                else if (line == "" && line2 != "")
                {
                    try
                    {
                        string msg = AES.Decrypt(line2, config.connKey);
                        MsgObj m = DeserializeJson<MsgObj>(msg);
                        if (m.type != "3" && m.type != "4")
                        {
                            sendmsg(m);
                            rdw.Write("\0");
                            rdw.Flush();
                        }
                        else if (m.type == "4")
                        {
                            rdw.Write("1\0");
                            rdw.Flush();
                        }
                        else
                        {
                            rdw.Write((chromeCurl == null ? "0" : chromeCurl) + "\0");
                            rdw.Flush();
                        }
                        line2 = "";
                    }
                    catch { }
                    break;
                }
                else
                {
                    line2 += line;
                }
            }
            try
            {
                Thread.Sleep(1000);
                rdr.Close();
                rdw.Close();
            }
            catch { }
        }
        public class MsgObj
        {
            public String type { set; get; }
            public String v1 { set; get; }
            public String v2 { set; get; }
        }

        public static T DeserializeJson<T>(string p_JsonStr)
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            return js.Deserialize<T>(p_JsonStr);
        }

        public void sendmsg(MsgObj m)
        {
            
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new msgdele(sendmsg), m);
            }
            else
            {
                try
                {
                    if (m.type != "1")
                    {
                        SendKeys.Send(zy(m.v1));
                    }
                    else
                    {
                        SendKeys.Send(zy(m.v1));
                        Thread.Sleep(100);
                        SendKeys.Send("{TAB}");
                        Thread.Sleep(500);
                        SendKeys.Send(zy(m.v2));
                    }
                    SendKeys.Flush();
                    
                }
                catch { }
            }
        }

        private string zy(String str)
        {
            String s1 = "+^%~(){}[]";
            for (int i = 0; i < s1.Length; i++)
            {
                str = str.Replace(s1[i].ToString(), "##AABB##" + s1[i].ToString() + "##BBAA##");
            }
            str = str.Replace("##AABB##", "{").Replace("##BBAA##", "}");
            return str;
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            notifyIcon1.Visible = false;
            Application.Exit();
        }

      

        

        object msgkey = new object();


        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (socketWorking)
            {
                socketWorking = false;
            }
            notifyIcon1.Visible = false;
            Application.Exit();
        }

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal; 
        }

        private void 设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SetConfig f = new SetConfig();
            f.form1 = this;
            f.ShowDialog();
        }
    }
}
